package com.gitee.hermer.engine.jars.app.sdk.configuration;

import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import com.gitee.hermer.boot.jee.commons.log.UtilsContext;
import com.gitee.hermer.engine.jars.app.sdk.EngineApplicationRefreshBeanEvent;
import com.gitee.hermer.engine.jars.app.sdk.annotate.EnableEngineScan;
import com.gitee.hermer.engine.jars.app.sdk.eventbus.EngineAppEventBusSender;
import com.gitee.hermer.engine.jars.app.sdk.processor.EngineJobBeanFactoryPostProcessor;
import com.gitee.hermer.engine.jars.app.sdk.utils.ResourcesUtils;
import com.gitee.hermer.engine.jars.core.app.domain.EngineAppContext;
import com.gitee.hermer.engine.jars.core.autoconfigure.annotate.ConditionalOnEngineApplication;
import com.gitee.hermer.engine.jars.core.domain.EngineConstant;

@Configuration
@Import({EngineAppXATransactionAutoConfiguration.class,EngineAppDisConfAutoConfiguration.class,
	EngineAppZipkinAutoConfiguration.class,EngineAppDubboZipkinAutoConfiguration.class,EngineAppTranManagementAutoConfiguration.class})
@ConditionalOnEngineApplication
public class EngineAppAutoConfiguration extends UtilsContext implements ImportAware,Ordered,ApplicationContextAware{

	private AnnotationAttributes metadataAttributes;

	private ApplicationContext selfContext;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.selfContext = applicationContext;
	}

	@Override
	public void setImportMetadata(AnnotationMetadata importMetadata) {
		if(importMetadata != null){
			Map<String, Object> attributes = importMetadata.getAnnotationAttributes(EnableEngineScan.class.getName(), false);
			this.metadataAttributes = AnnotationAttributes.fromMap(attributes);
		}
		info("AnnotationMetadata -> [%s]",this.metadataAttributes.toString());
	}

	@Bean
	public EngineApplicationRefreshBeanEvent engineApplicationRefreshBeanEvent(){
		return new EngineApplicationRefreshBeanEvent();
	}
	
	@Bean
	public ResourcesUtils resourcesUtils(){
		return new ResourcesUtils();
	}
	
	@Bean
	public EngineAppEventBusSender engineAppEventBusSender(){
		return new EngineAppEventBusSender();
	}

	@Bean
	public EngineAppContext appJobContext(){
		try{
			info("初始化EngineAppJobContext...");
			return new EngineAppContext(selfContext);
		}catch (Exception e) {
			error(e.getMessage(),e);
		}
		return null;
	}

	@Bean
	public EngineJobBeanFactoryPostProcessor engineJobBeanFactoryPostProcessor(){
		if(metadataAttributes == null)
			throw new BeanCreationException("not find @EnableEngineScan attributes");
		return new EngineJobBeanFactoryPostProcessor(metadataAttributes.getStringArray(EngineConstant.ANNOTATE_FIELD_NAME_BASE_PACKAGES));
	}

	@Override
	public int getOrder() {
		return HIGHEST_PRECEDENCE + 1000;
	}
}
